using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace MyMedia.iPod
{
	// Used mostly for strings, but also thumbnails (not supported at the moment)
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	unsafe struct Mhod
	{
		public fixed byte Identifier[4];
		public int HeaderLength;
		public int TotalLength;
		public int Type;
		public int Unknown1;
		public int Unknown2;

		public static Mhod Create()
		{
			Mhod mhod = new Mhod();
			mhod.Identifier[0] = (byte)'m';
			mhod.Identifier[1] = (byte)'h';
			mhod.Identifier[2] = (byte)'o';
			mhod.Identifier[3] = (byte)'d';

			mhod.HeaderLength = sizeof(Mhod);
			mhod.TotalLength = 0;
			mhod.Type = 0;
			mhod.Unknown1 = 0;
			mhod.Unknown1 = 0;

			return mhod;
		}

		public void Read(BinaryReader reader)
		{
			byte[] data = reader.ReadBytes(sizeof(Mhod));
			fixed (byte* pData = data)
			{
				this = *(Mhod*)pData;
			}
		}

		public void Write(BinaryWriter writer)
		{
			byte[] data = StructUtil.GetBytes(this);
			writer.Write(data);
		}
	}

	struct MhodBlob
	{
		public byte[] Data;

		public void Read(BinaryReader reader, int length)
		{
			Data = reader.ReadBytes(length);
		}

		public void Write(BinaryWriter writer)
		{
			writer.Write(Data);
		}
	}

	// Utility struct for Mhod used for strings
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	unsafe struct MhodString
	{
		public int Position;
		public int Length;
		public int Unknown3;
		public int Unknown4;
		public byte[] String;

		public static MhodString Create(string value)
		{
			MhodString mhodString = new MhodString();
			mhodString.Position = 1;
			mhodString.Unknown3 = 0;
			mhodString.Unknown4 = 0;
			UnicodeEncoding encoding = new UnicodeEncoding();
			byte[] data = encoding.GetBytes(value.ToCharArray());
			mhodString.Length = data.Length;
			mhodString.String = data;
			
			return mhodString;
		}
		
		public void Read(BinaryReader reader)
		{
			Position = reader.ReadInt32();
			Length = reader.ReadInt32();
			Unknown3 = reader.ReadInt32();
			Unknown4 = reader.ReadInt32();
			String = reader.ReadBytes(Length);
		}

		public void Write(BinaryWriter writer)
		{
			writer.Write(Position);
			writer.Write(Length);
			writer.Write(Unknown3);
			writer.Write(Unknown4);
			writer.Write(String);
		}
	}
}
